package com.xqboss.generator;


import com.baomidou.mybatisplus.annotation.DbType;
import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.converts.MySqlTypeConvert;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.DbColumnType;
import com.baomidou.mybatisplus.generator.config.rules.IColumnType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import lombok.extern.slf4j.Slf4j;

import java.io.File;
import java.util.HashMap;
import java.util.Map;


@Slf4j
public class Generator {
    static String serverPrefix = "sys";
    //    static String controllerAuth = ".c";
    static String[] tables = new String[]{"sys_announcement_category"};
    static boolean isApp = false;

    public static void main(String[] args) {
        // 自定义模板配置，可以 copy 源码 mybatis-plus/src/main/resources/templates 下面内容修改，
        // 放置自己项目的 src/main/resources/templates 目录下, 默认名称一下可以不配置，也可以自定义模板名称
        TemplateConfig tc = new TemplateConfig();
        tc.setController("vm/java/controller2.java.vm");
        tc.setMapper("vm/java/mapper2.java.vm");
        tc.setService("vm/java/service2.java.vm");
        tc.setEntity("vm/java/entity2.java.vm");
        tc.setXml("vm/xml/mapper2.xml.vm");
        tc.setController(null);
//        tc.setMapper(null);
//        tc.setService(null);
//        tc.setEntity(null);
        tc.setXml(null);
        AutoGenerator mpg = new AutoGenerator();
        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        String property = System.getProperty("user.dir");
        String projectPath;
        if (property.contains("matao")) {
            projectPath = property + "/xqboss-apps/";
        } else {
            projectPath = property + "\\xqboss-apps\\";
        }
        // 生成文件的输出目录
        gc.setOutputDir(projectPath + "/src/main/java");
        gc.setAuthor(System.getenv("discoverNameSpace"));
        // 生成后打开目录
        gc.setOpen(false);
        // 设置时间类型使用哪个包下的
        gc.setDateType(DateType.ONLY_DATE);
        gc.setFileOverride(true);// 是否覆盖同名文件，默认是false
        gc.setActiveRecord(false);// 不需要ActiveRecord特性的请改为false
        gc.setEnableCache(false);// XML 二级缓存
        gc.setBaseResultMap(false);// XML ResultMap
        gc.setBaseColumnList(false);// XML columList
        gc.setSwagger2(true);
        /* 自定义文件命名，注意 %s 会自动填充表实体属性！ */
        gc.setServiceName("%sService");
        mpg.setGlobalConfig(gc);

        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setDbType(DbType.MYSQL);
        dsc.setUrl(GeneratorEnum.dbUrl);
        dsc.setDriverName(GeneratorEnum.driverName);
        dsc.setUsername(GeneratorEnum.username);
        dsc.setPassword(GeneratorEnum.password);
        mpg.setDataSource(dsc);
        dsc.setTypeConvert(new MySqlTypeConvertCustom());


        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        strategy.setEntityLombokModel(true);
        strategy.setEntitySerialVersionUID(true);
        strategy.setInclude(tables); // 需要生成的表
        mpg.setStrategy(strategy);

        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setParent("").setEntity("com.xqboss.apps.domain." + serverPrefix)
                .setMapper("com.xqboss.apps.mapper." + serverPrefix)
                .setService("com.xqboss.apps.service." + serverPrefix)
                .setController((isApp ? "com.xqboss.apps.controller." : "com.xqboss.web.controller.") + serverPrefix)
                .setXml("com.xqboss.apps.mapper." + serverPrefix);
        mpg.setPackageInfo(pc);


        // 注入自定义配置，可以在 VM 中使用 cfg.abc 【可无】
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
            }
            @Override
            public Map<String, Object> prepareObjectMap(Map<String, Object> objectMap) {
//                objectMap.put("serverAuth", StrUtil.isEmpty(controllerAuth) ? "" : controllerAuth);
                objectMap.put("selfCPath", isApp ? "/apps": "/web");

                return objectMap;
            }
        };
        mpg.setCfg(cfg);


//         如上任何一个模块如果设置 空 OR Null 将不生成该模块。
        mpg.setTemplate(tc);

        Map<String, String> pathInfo = new HashMap<String, String>();

        pathInfo.put(ConstVal.ENTITY_PATH, joinPath(gc.getOutputDir(), joinPackage(pc.getParent(), pc.getEntity())));
        pathInfo.put(ConstVal.MAPPER_PATH, joinPath(gc.getOutputDir(), joinPackage(pc.getParent(), pc.getMapper())));
        pathInfo.put(ConstVal.XML_PATH, joinPath(projectPath, "\\src\\main\\resources\\mapper\\apps\\" + serverPrefix));
        pathInfo.put(ConstVal.CONTROLLER_PATH, joinPath(System.getProperty("user.dir") + "/xqboss-admin/src/main/java", joinPackage(pc.getParent(), pc.getController())));
        pathInfo.put(ConstVal.SERVICE_PATH, joinPath(gc.getOutputDir(), joinPackage(pc.getParent(), pc.getService())));
        pc.setPathInfo(pathInfo);
        try {
            // 执行生成
            mpg.execute();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 连接路径字符串
     *
     * @param parentDir   路径常量字符串
     * @param packageName 包名
     * @return 连接后的路径
     */
    private static String joinPath(String parentDir, String packageName) {
        if (StringUtils.isBlank(parentDir)) {
            parentDir = System.getProperty(ConstVal.JAVA_TMPDIR);
        }
        if (!StringUtils.endsWith(parentDir, File.separator)) {
            parentDir += File.separator;
        }
        packageName = packageName.replaceAll("\\.", StringPool.BACK_SLASH + File.separator);
        return parentDir + packageName;
    }

    /**
     * 连接父子包名
     *
     * @param parent     父包名
     * @param subPackage 子包名
     * @return 连接后的包名
     */
    private static String joinPackage(String parent, String subPackage) {
        return StringUtils.isBlank(parent) ? subPackage : (parent + StringPool.DOT + subPackage);
    }

    /**
     * 自定义类型转换
     */
    static class MySqlTypeConvertCustom extends MySqlTypeConvert implements ITypeConvert {
        @Override
        public IColumnType processTypeConvert(GlobalConfig globalConfig, String fieldType) {
            String t = fieldType.toLowerCase();
            if (t.contains("tinyint")) {
                return DbColumnType.INTEGER;
            }
            return super.processTypeConvert(globalConfig, fieldType);
        }
    }
}
